library(dplyr)
library(tidyr)
library(here)
library(readr)
library(ggplot2)
library(googlesheets4)
library(vegan)
library(readxl)

#Analysis

gURL <- "https://docs.google.com/spreadsheets/d/1GKWzD0q683oH3I_i5ueulbf4P4Q-9-a9YPbdyUZyF2A/edit#gid=847966271"

Meta <- read_sheet(gURL, sheet = "Sample_data_corr") %>% 
  select(Sample_names, Sites, Sampler, duration, Type)
✔ Reading from sampler_comp_meta.
✔ Range ''Sample_data_corr''.
Plates <- read_sheet(gURL, sheet = "Plates", range = "A26:M44", col_types = "c") %>% 
  dplyr::rename(row = 1) %>% 
  filter(row %in% LETTERS[1:8]) %>% 
  mutate(Plate = rep(c("Plate_1", "Plate_2"), each = 8)) %>% 
  pivot_longer(!one_of(c("row", "Plate")), names_to = "col", values_to = "Sample_names") %>% 
  select(Plate, row, col, Sample_names) 
✔ Reading from sampler_comp_meta.
✔ Range ''Plates'!A26:M44'.
Plates <- 
Plates %>% 
  filter(!is.na(Sample_names)) %>% 
  left_join(Meta) %>% 
  mutate(Type = case_when(grepl("PCR", Sample_names) ~ "PCR_control",
                          TRUE ~ Type))
Joining with `by = join_by(Sample_names)`
  
  

shini_barcodes <- 
  read_xlsx(here("Documents", "Shini_barcodes_4_plates.xlsx")) %>% 
  mutate(Plate = rep(rep(paste("Plate", 1:4, sep = "_"), each = 96),2)) %>% 
  filter(Plate %in% c("Plate_1", "Plate_2")) %>% 
  dplyr::rename(Index = 1) %>% 
  select(Index, Plate) %>% 
  filter(grepl("_i5$", Index)) %>% 
  mutate(Index = gsub("(.+?)_i5", "\\1", Index)) %>% 
  group_by(Plate) %>% 
  mutate(row = rep(LETTERS[1:8], each = 12)) %>% 
  mutate(col = as.character(rep(1:12, 8)))

ASV_sp <- read_tsv(here("Data", "iSeq", "ITS_ASW_glom.txt"))
Rows: 169 Columns: 399── Column specification ────────────────────────────────────────────────────────────────────────────────
Delimiter: "\t"
chr   (1): Sample
dbl (398): seq_0001, seq_0003, seq_0004, seq_0009, seq_0010, seq_0011, seq_0013, seq_0016, seq_0018,...
ℹ Use `spec()` to retrieve the full column specification for this data.
ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
ITS_taxa_80_glom <- read_tsv(here("Data","iSeq", "ITS_taxa_80_glom.txt"))
Rows: 398 Columns: 8── Column specification ────────────────────────────────────────────────────────────────────────────────
Delimiter: "\t"
chr (8): seq, kingdom, phylum, class, order, family, genus, species
ℹ Use `spec()` to retrieve the full column specification for this data.
ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
DNAC <- read_tsv(here("Data", "DNA_conc_air_sampler_comp.txt"))
Rows: 304 Columns: 17── Column specification ────────────────────────────────────────────────────────────────────────────────
Delimiter: "\t"
chr  (12): Sample_names, Sites, Sampler, duration, Type, Tube, Material, Site_Code, Sampler_Code, Co...
dbl   (4): OD, Buffer_vol, Date_Code, DNAC
dttm  (1): Dates
ℹ Use `spec()` to retrieve the full column specification for this data.
ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.

clean


Fungi_ASV <- 
ITS_taxa_80_glom %>% 
  filter(phylum %in% c("Ascomycota", "Basidiomycota")) %>% 
  pull(seq)

ASV_sp <- ASV_sp[,colnames(ASV_sp) %in% c("Sample", Fungi_ASV)]
  
Meta <- 
Plates %>% 
  left_join(shini_barcodes)
Joining with `by = join_by(Plate, row, col)`
flow_rate <- 
  Meta %>% 
  filter(Type == "active" & Sampler != "Drone") %>% 
  select(Sampler, duration) %>% 
  distinct() %>% 
  mutate(flow = case_when(
    Sampler == "Hepa" ~ 60,
    Sampler == "Kärcher" ~ 3000,
    Sampler == "Sass" ~ 300,
    Sampler == "Coriolis" ~ 300,
    Sampler == "Electrostatic" ~ 10,
    Sampler == "Burkhart" ~ 16.5,
  )) %>% 
  mutate(air_vol = case_when(
    duration == "30 min" ~ flow*30,
    duration == "5 hours" ~ flow*5*60
  ))
ASV_tax_long <- 
ASV_sp %>% 
  pivot_longer(-Sample, names_to = "seq", values_to = "reads") %>% 
  dplyr::rename(Index = Sample) %>% 
  left_join(Meta) %>% 
  left_join(ITS_taxa_80_glom)
Joining with `by = join_by(Index)`Joining with `by = join_by(seq)`

clean data

PCR blanks


ASV_tax_long %>% 
  filter(grepl("control", Type)) %>% 
  filter(reads > 0) %>% 
  group_by(Type) %>% 
  summarise(reads = sum(reads))
NA

ASV_tax_long %>% 
  mutate(reads = ifelse(reads == 0, NA, reads)) %>% 
  arrange(Type, Sites, duration) %>% 
 # filter(Sampler == "MWAC") %>% 
  mutate(Sample_names = factor(Sample_names, levels = unique(.$Sample_names))) %>% 
  ggplot(aes(y = species, x = Sample_names, size = reads, colour = Type))+
  geom_point()+
  theme(axis.text.x = element_text(angle = 90, vjust = 0.5))

NA

rar_curve <- 
ASV_sp %>% 
  select(-Sample) %>% 
  as.matrix %>% 
  `rownames<-`(ASV_sp$Sample) %>% 
  `[`(rowSums(.) > 0,) %>% 
  rarecurve(x = .,step = 100, tidy = TRUE)

rar_curve %>% left_join(Meta, by = c("Site" = "Index")) %>% 
  filter(grepl("active|passive", Type)) %>% 
  ggplot(aes(x = Sample, y = Species, group = Site, colour = duration)) +
  geom_line()+
  facet_wrap(~Sampler)

rar <- 
ASV_sp %>% 
  select(-Sample) %>% 
  as.matrix %>% 
  `rownames<-`(ASV_sp$Sample) %>% 
  `[`(rowSums(.) > 0,) %>% 
  rarefy(x = .,sample = 2000) 
Warning: requested 'sample' was larger than smallest site maximum (1)

S_df <- 
rar %>% 
  data.frame(S = .) %>% 
  dplyr::add_rownames(var = "Index") %>% 
  left_join(Meta) %>% 
  filter(Type %in% c("active", "passive")) %>% 
  filter(Sampler != "Drone") %>% 
  mutate(Sampler = factor(Sampler, levels= unique(.$Sampler)[c(8,1,3,2,5,6,4,7)])) 
Warning: `add_rownames()` was deprecated in dplyr 1.0.0.
Please use `tibble::rownames_to_column()` instead.Joining with `by = join_by(Index)`
S_df %>% 
  ggplot(aes(y = S, x = duration,  colour = Sites))+
  facet_grid(~Sampler, scales = "free_x")+
  geom_line(aes(group = Sites), size = 0.2, colour = "grey")+
  geom_point()+
  theme_minimal()+
  scale_color_brewer(palette = "Set1")+
  theme(axis.text.x = element_text(angle = 90, vjust = 0.5),
        legend.position = "bottom")
Warning: Using `size` aesthetic for lines was deprecated in ggplot2 3.4.0.
Please use `linewidth` instead.

S_df %>% 
  left_join(flow_rate) %>% 
  filter(Type == "active" & Sampler != "Drone") %>% 
  ggplot(aes(x = air_vol, y = S, colour = Sampler))+
  geom_line(aes(group = Sites), size = 0.2, colour = "grey")+
  geom_point()+
  facet_grid(~duration)+
  scale_x_log10()+
  scale_color_brewer(palette = "Set1")+
  theme_bw()
Joining with `by = join_by(Sampler, duration)`

NA
NA

#Agaricomycetes

ASV_tax_long %>% 
  filter(class == "Agaricomycetes") %>% 
  #filter(phylum == "Basidiomycota") %>% 
  filter(!is.na(species)) %>% 
  filter(Type %in% c("active", "passive")) %>% 
  filter(duration != "30 min") %>% 
  filter(Sampler != "Drone") %>% 
  mutate(Sampler = factor(Sampler, levels= unique(.$Sampler)[c(8,1,3,2,5,6,4,7)])) %>% 
  mutate(reads = ifelse(reads == 0, NA, reads)) %>% 
  arrange(Type, Sites, duration) %>% 
 # filter(Sampler == "MWAC") %>% 
  mutate(Sample_names = factor(Sample_names, levels = unique(.$Sample_names))) %>% 
  ggplot(aes(y = species, x = Sampler, size = reads, colour = duration))+
  geom_point(alpha = 0.6)+
  facet_grid(~Sites, scales = "free_x")+
  theme(axis.text.x = element_text(angle = 90, vjust = 0.5))+
  scale_color_brewer(palette = "Set1")+
  ggtitle("Species composition by site - Agaricomycetes")

NA
ASV_agri <- ITS_taxa_80_glom %>% 
  filter(class == "Agaricomycetes") %>% 
  pull(seq)
  

rar_agri <- 
ASV_sp %>% 
  select(all_of(ASV_agri)) %>% 
  as.matrix %>% 
  `rownames<-`(ASV_sp$Sample) %>% 
  `[`(rowSums(.) > 0,) %>% 
  rarefy(x = .,sample = 2000) 
Warning: requested 'sample' was larger than smallest site maximum (1)

S_df_agri <- 
rar_agri %>% 
  data.frame(S = .) %>% 
  dplyr::add_rownames(var = "Index") %>% 
  left_join(Meta) %>% 
  filter(Type %in% c("active", "passive")) %>% 
  filter(Sampler != "Drone") %>% 
  mutate(Sampler = factor(Sampler, levels= unique(.$Sampler)[c(8,1,3,2,5,6,4,7)])) 
Warning: `add_rownames()` was deprecated in dplyr 1.0.0.
Please use `tibble::rownames_to_column()` instead.Joining with `by = join_by(Index)`
S_df_agri %>% 
  ggplot(aes(y = S, x = duration,  colour = Sites))+
  facet_grid(~Sampler, scales = "free_x")+
  geom_line(aes(group = Sites), size = 0.2, colour = "grey")+
  geom_point()+
  theme_minimal()+
  scale_color_brewer(palette = "Set1")+
  theme(axis.text.x = element_text(angle = 90, vjust = 0.5),
        legend.position = "bottom")+
  ggtitle("rarefied richness - Agaricomycetes")

S_df_agri %>% 
  left_join(flow_rate) %>% 
  filter(Type == "active" & Sampler != "Drone") %>% 
  ggplot(aes(x = air_vol, y = S, colour = Sampler))+
 # geom_line(aes(group = Sites), size = 0.2, colour = "grey")+
  geom_point(position = position_jitter(width = 0.1))+
  geom_smooth(aes(group = 1), method = "lm", se = TRUE, colour = "black", size = 0.2)+
  facet_grid(~duration)+
  scale_x_log10()+
  scale_color_brewer(palette = "Set1")+
  theme_minimal()+
  theme(legend.position = "bottom")+
  labs(x = "sampled air volume (l)", title = "sampled air volume")
Joining with `by = join_by(Sampler, duration)`

NA
NA
S_df_agri %>% 
  left_join(flow_rate) %>% 
  left_join(DNAC) %>% 
  mutate(yield = DNAC * 200) %>% 
  filter(Type %in% c("active", "passive") & Sampler != "Drone") %>% 
  ggplot(aes(x = yield, y = S, colour = Sampler))+
 # geom_line(aes(group = Sites), size = 0.2, colour = "grey")+
  geom_point(position = position_jitter(width = 0.1))+
  geom_smooth(aes(group = 1), method = "lm", se = TRUE, colour = "black", size = 0.2)+
  facet_grid(~duration)+
  scale_x_log10()+
  scale_color_brewer(palette = "Set1")+
  theme_minimal()+
  theme(legend.position = "bottom")+
  labs(x = "DNA yield (ng)", title = "DNA yield")
Joining with `by = join_by(Sampler, duration)`Joining with `by = join_by(Plate, Sample_names, Sites, Sampler, duration, Type)`

LS0tCnRpdGxlOiAiRnVuZ2kgaVNlcSBkYXRhIGFuYWx5c2lzIgpvdXRwdXQ6IGh0bWxfbm90ZWJvb2sKLS0tCgpgYGB7cn0KbGlicmFyeShkcGx5cikKbGlicmFyeSh0aWR5cikKbGlicmFyeShoZXJlKQpsaWJyYXJ5KHJlYWRyKQpsaWJyYXJ5KGdncGxvdDIpCmxpYnJhcnkoZ29vZ2xlc2hlZXRzNCkKbGlicmFyeSh2ZWdhbikKbGlicmFyeShyZWFkeGwpCmBgYAoKI0FuYWx5c2lzCmBgYHtyfQpnVVJMIDwtICJodHRwczovL2RvY3MuZ29vZ2xlLmNvbS9zcHJlYWRzaGVldHMvZC8xR0tXekQwcTY4M29IM0lfaTV1ZXVsYmY0UDRRLTktYTlZUGJkeVVaeUYyQS9lZGl0I2dpZD04NDc5NjYyNzEiCgpNZXRhIDwtIHJlYWRfc2hlZXQoZ1VSTCwgc2hlZXQgPSAiU2FtcGxlX2RhdGFfY29yciIpICU+JSAKICBzZWxlY3QoU2FtcGxlX25hbWVzLCBTaXRlcywgU2FtcGxlciwgZHVyYXRpb24sIFR5cGUpCgoKUGxhdGVzIDwtIHJlYWRfc2hlZXQoZ1VSTCwgc2hlZXQgPSAiUGxhdGVzIiwgcmFuZ2UgPSAiQTI2Ok00NCIsIGNvbF90eXBlcyA9ICJjIikgJT4lIAogIGRwbHlyOjpyZW5hbWUocm93ID0gMSkgJT4lIAogIGZpbHRlcihyb3cgJWluJSBMRVRURVJTWzE6OF0pICU+JSAKICBtdXRhdGUoUGxhdGUgPSByZXAoYygiUGxhdGVfMSIsICJQbGF0ZV8yIiksIGVhY2ggPSA4KSkgJT4lIAogIHBpdm90X2xvbmdlcighb25lX29mKGMoInJvdyIsICJQbGF0ZSIpKSwgbmFtZXNfdG8gPSAiY29sIiwgdmFsdWVzX3RvID0gIlNhbXBsZV9uYW1lcyIpICU+JSAKICBzZWxlY3QoUGxhdGUsIHJvdywgY29sLCBTYW1wbGVfbmFtZXMpIAoKClBsYXRlcyA8LSAKUGxhdGVzICU+JSAKICBmaWx0ZXIoIWlzLm5hKFNhbXBsZV9uYW1lcykpICU+JSAKICBsZWZ0X2pvaW4oTWV0YSkgJT4lIAogIG11dGF0ZShUeXBlID0gY2FzZV93aGVuKGdyZXBsKCJQQ1IiLCBTYW1wbGVfbmFtZXMpIH4gIlBDUl9jb250cm9sIiwKICAgICAgICAgICAgICAgICAgICAgICAgICBUUlVFIH4gVHlwZSkpCiAgCiAgCgpzaGluaV9iYXJjb2RlcyA8LSAKICByZWFkX3hsc3goaGVyZSgiRG9jdW1lbnRzIiwgIlNoaW5pX2JhcmNvZGVzXzRfcGxhdGVzLnhsc3giKSkgJT4lIAogIG11dGF0ZShQbGF0ZSA9IHJlcChyZXAocGFzdGUoIlBsYXRlIiwgMTo0LCBzZXAgPSAiXyIpLCBlYWNoID0gOTYpLDIpKSAlPiUgCiAgZmlsdGVyKFBsYXRlICVpbiUgYygiUGxhdGVfMSIsICJQbGF0ZV8yIikpICU+JSAKICBkcGx5cjo6cmVuYW1lKEluZGV4ID0gMSkgJT4lIAogIHNlbGVjdChJbmRleCwgUGxhdGUpICU+JSAKICBmaWx0ZXIoZ3JlcGwoIl9pNSQiLCBJbmRleCkpICU+JSAKICBtdXRhdGUoSW5kZXggPSBnc3ViKCIoLis/KV9pNSIsICJcXDEiLCBJbmRleCkpICU+JSAKICBncm91cF9ieShQbGF0ZSkgJT4lIAogIG11dGF0ZShyb3cgPSByZXAoTEVUVEVSU1sxOjhdLCBlYWNoID0gMTIpKSAlPiUgCiAgbXV0YXRlKGNvbCA9IGFzLmNoYXJhY3RlcihyZXAoMToxMiwgOCkpKQoKQVNWX3NwIDwtIHJlYWRfdHN2KGhlcmUoIkRhdGEiLCAiaVNlcSIsICJJVFNfQVNXX2dsb20udHh0IikpCklUU190YXhhXzgwX2dsb20gPC0gcmVhZF90c3YoaGVyZSgiRGF0YSIsImlTZXEiLCAiSVRTX3RheGFfODBfZ2xvbS50eHQiKSkKCkROQUMgPC0gcmVhZF90c3YoaGVyZSgiRGF0YSIsICJETkFfY29uY19haXJfc2FtcGxlcl9jb21wLnR4dCIpKQoKYGBgCgpjbGVhbgoKYGBge3J9CgpGdW5naV9BU1YgPC0gCklUU190YXhhXzgwX2dsb20gJT4lIAogIGZpbHRlcihwaHlsdW0gJWluJSBjKCJBc2NvbXljb3RhIiwgIkJhc2lkaW9teWNvdGEiKSkgJT4lIAogIHB1bGwoc2VxKQoKQVNWX3NwIDwtIEFTVl9zcFssY29sbmFtZXMoQVNWX3NwKSAlaW4lIGMoIlNhbXBsZSIsIEZ1bmdpX0FTVildCiAgCmBgYAoKYGBge3J9Ck1ldGEgPC0gClBsYXRlcyAlPiUgCiAgbGVmdF9qb2luKHNoaW5pX2JhcmNvZGVzKQpgYGAKCmBgYHtyfQpmbG93X3JhdGUgPC0gCiAgTWV0YSAlPiUgCiAgZmlsdGVyKFR5cGUgPT0gImFjdGl2ZSIgJiBTYW1wbGVyICE9ICJEcm9uZSIpICU+JSAKICBzZWxlY3QoU2FtcGxlciwgZHVyYXRpb24pICU+JSAKICBkaXN0aW5jdCgpICU+JSAKICBtdXRhdGUoZmxvdyA9IGNhc2Vfd2hlbigKICAgIFNhbXBsZXIgPT0gIkhlcGEiIH4gNjAsCiAgICBTYW1wbGVyID09ICJLw6RyY2hlciIgfiAzMDAwLAogICAgU2FtcGxlciA9PSAiU2FzcyIgfiAzMDAsCiAgICBTYW1wbGVyID09ICJDb3Jpb2xpcyIgfiAzMDAsCiAgICBTYW1wbGVyID09ICJFbGVjdHJvc3RhdGljIiB+IDEwLAogICAgU2FtcGxlciA9PSAiQnVya2hhcnQiIH4gMTYuNSwKICApKSAlPiUgCiAgbXV0YXRlKGFpcl92b2wgPSBjYXNlX3doZW4oCiAgICBkdXJhdGlvbiA9PSAiMzAgbWluIiB+IGZsb3cqMzAsCiAgICBkdXJhdGlvbiA9PSAiNSBob3VycyIgfiBmbG93KjUqNjAKICApKQpgYGAKCgpgYGB7cn0KQVNWX3RheF9sb25nIDwtIApBU1Zfc3AgJT4lIAogIHBpdm90X2xvbmdlcigtU2FtcGxlLCBuYW1lc190byA9ICJzZXEiLCB2YWx1ZXNfdG8gPSAicmVhZHMiKSAlPiUgCiAgZHBseXI6OnJlbmFtZShJbmRleCA9IFNhbXBsZSkgJT4lIAogIGxlZnRfam9pbihNZXRhKSAlPiUgCiAgbGVmdF9qb2luKElUU190YXhhXzgwX2dsb20pCmBgYAoKIyBjbGVhbiBkYXRhCgojIyBQQ1IgYmxhbmtzCmBgYHtyfQoKQVNWX3RheF9sb25nICU+JSAKICBmaWx0ZXIoZ3JlcGwoImNvbnRyb2wiLCBUeXBlKSkgJT4lIAogIGZpbHRlcihyZWFkcyA+IDApICU+JSAKICBncm91cF9ieShUeXBlKSAlPiUgCiAgc3VtbWFyaXNlKHJlYWRzID0gc3VtKHJlYWRzKSkKCmBgYAoKYGBge3J9CgpBU1ZfdGF4X2xvbmcgJT4lIAogIG11dGF0ZShyZWFkcyA9IGlmZWxzZShyZWFkcyA9PSAwLCBOQSwgcmVhZHMpKSAlPiUgCiAgYXJyYW5nZShUeXBlLCBTaXRlcywgZHVyYXRpb24pICU+JSAKICMgZmlsdGVyKFNhbXBsZXIgPT0gIk1XQUMiKSAlPiUgCiAgbXV0YXRlKFNhbXBsZV9uYW1lcyA9IGZhY3RvcihTYW1wbGVfbmFtZXMsIGxldmVscyA9IHVuaXF1ZSguJFNhbXBsZV9uYW1lcykpKSAlPiUgCiAgZ2dwbG90KGFlcyh5ID0gc3BlY2llcywgeCA9IFNhbXBsZV9uYW1lcywgc2l6ZSA9IHJlYWRzLCBjb2xvdXIgPSBUeXBlKSkrCiAgZ2VvbV9wb2ludCgpKwogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gOTAsIHZqdXN0ID0gMC41KSkKICAKYGBgCgpgYGB7cn0KCnJhcl9jdXJ2ZSA8LSAKQVNWX3NwICU+JSAKICBzZWxlY3QoLVNhbXBsZSkgJT4lIAogIGFzLm1hdHJpeCAlPiUgCiAgYHJvd25hbWVzPC1gKEFTVl9zcCRTYW1wbGUpICU+JSAKICBgW2Aocm93U3VtcyguKSA+IDAsKSAlPiUgCiAgcmFyZWN1cnZlKHggPSAuLHN0ZXAgPSAxMDAsIHRpZHkgPSBUUlVFKQoKcmFyX2N1cnZlICU+JSBsZWZ0X2pvaW4oTWV0YSwgYnkgPSBjKCJTaXRlIiA9ICJJbmRleCIpKSAlPiUgCiAgZmlsdGVyKGdyZXBsKCJhY3RpdmV8cGFzc2l2ZSIsIFR5cGUpKSAlPiUgCiAgZ2dwbG90KGFlcyh4ID0gU2FtcGxlLCB5ID0gU3BlY2llcywgZ3JvdXAgPSBTaXRlLCBjb2xvdXIgPSBkdXJhdGlvbikpICsKICBnZW9tX2xpbmUoKSsKICBmYWNldF93cmFwKH5TYW1wbGVyKQoKYGBgCgoKCgpgYGB7cn0KcmFyIDwtIApBU1Zfc3AgJT4lIAogIHNlbGVjdCgtU2FtcGxlKSAlPiUgCiAgYXMubWF0cml4ICU+JSAKICBgcm93bmFtZXM8LWAoQVNWX3NwJFNhbXBsZSkgJT4lIAogIGBbYChyb3dTdW1zKC4pID4gMCwpICU+JSAKICByYXJlZnkoeCA9IC4sc2FtcGxlID0gMjAwMCkgCgpgYGAKCmBgYHtyfQoKU19kZiA8LSAKcmFyICU+JSAKICBkYXRhLmZyYW1lKFMgPSAuKSAlPiUgCiAgZHBseXI6OmFkZF9yb3duYW1lcyh2YXIgPSAiSW5kZXgiKSAlPiUgCiAgbGVmdF9qb2luKE1ldGEpICU+JSAKICBmaWx0ZXIoVHlwZSAlaW4lIGMoImFjdGl2ZSIsICJwYXNzaXZlIikpICU+JSAKICBmaWx0ZXIoU2FtcGxlciAhPSAiRHJvbmUiKSAlPiUgCiAgbXV0YXRlKFNhbXBsZXIgPSBmYWN0b3IoU2FtcGxlciwgbGV2ZWxzPSB1bmlxdWUoLiRTYW1wbGVyKVtjKDgsMSwzLDIsNSw2LDQsNyldKSkgCgpTX2RmICU+JSAKICBnZ3Bsb3QoYWVzKHkgPSBTLCB4ID0gZHVyYXRpb24sICBjb2xvdXIgPSBTaXRlcykpKwogIGZhY2V0X2dyaWQoflNhbXBsZXIsIHNjYWxlcyA9ICJmcmVlX3giKSsKICBnZW9tX2xpbmUoYWVzKGdyb3VwID0gU2l0ZXMpLCBzaXplID0gMC4yLCBjb2xvdXIgPSAiZ3JleSIpKwogIGdlb21fcG9pbnQoKSsKICB0aGVtZV9taW5pbWFsKCkrCiAgc2NhbGVfY29sb3JfYnJld2VyKHBhbGV0dGUgPSAiU2V0MSIpKwogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gOTAsIHZqdXN0ID0gMC41KSwKICAgICAgICBsZWdlbmQucG9zaXRpb24gPSAiYm90dG9tIikKYGBgCgpgYGB7cn0KU19kZiAlPiUgCiAgbGVmdF9qb2luKGZsb3dfcmF0ZSkgJT4lIAogIGZpbHRlcihUeXBlID09ICJhY3RpdmUiICYgU2FtcGxlciAhPSAiRHJvbmUiKSAlPiUgCiAgZ2dwbG90KGFlcyh4ID0gYWlyX3ZvbCwgeSA9IFMsIGNvbG91ciA9IFNhbXBsZXIpKSsKICBnZW9tX2xpbmUoYWVzKGdyb3VwID0gU2l0ZXMpLCBzaXplID0gMC4yLCBjb2xvdXIgPSAiZ3JleSIpKwogIGdlb21fcG9pbnQoKSsKICBmYWNldF9ncmlkKH5kdXJhdGlvbikrCiAgc2NhbGVfeF9sb2cxMCgpKwogIHNjYWxlX2NvbG9yX2JyZXdlcihwYWxldHRlID0gIlNldDEiKSsKICB0aGVtZV9idygpCiAgCgpgYGAKCiNBZ2FyaWNvbXljZXRlcwoKYGBge3J9CkFTVl90YXhfbG9uZyAlPiUgCiAgZmlsdGVyKGNsYXNzID09ICJBZ2FyaWNvbXljZXRlcyIpICU+JSAKICAjZmlsdGVyKHBoeWx1bSA9PSAiQmFzaWRpb215Y290YSIpICU+JSAKICBmaWx0ZXIoIWlzLm5hKHNwZWNpZXMpKSAlPiUgCiAgZmlsdGVyKFR5cGUgJWluJSBjKCJhY3RpdmUiLCAicGFzc2l2ZSIpKSAlPiUgCiAgZmlsdGVyKGR1cmF0aW9uICE9ICIzMCBtaW4iKSAlPiUgCiAgZmlsdGVyKFNhbXBsZXIgIT0gIkRyb25lIikgJT4lIAogIG11dGF0ZShTYW1wbGVyID0gZmFjdG9yKFNhbXBsZXIsIGxldmVscz0gdW5pcXVlKC4kU2FtcGxlcilbYyg4LDEsMywyLDUsNiw0LDcpXSkpICU+JSAKICBtdXRhdGUocmVhZHMgPSBpZmVsc2UocmVhZHMgPT0gMCwgTkEsIHJlYWRzKSkgJT4lIAogIGFycmFuZ2UoVHlwZSwgU2l0ZXMsIGR1cmF0aW9uKSAlPiUgCiAjIGZpbHRlcihTYW1wbGVyID09ICJNV0FDIikgJT4lIAogIG11dGF0ZShTYW1wbGVfbmFtZXMgPSBmYWN0b3IoU2FtcGxlX25hbWVzLCBsZXZlbHMgPSB1bmlxdWUoLiRTYW1wbGVfbmFtZXMpKSkgJT4lIAogIGdncGxvdChhZXMoeSA9IHNwZWNpZXMsIHggPSBTYW1wbGVyLCBzaXplID0gcmVhZHMsIGNvbG91ciA9IGR1cmF0aW9uKSkrCiAgZ2VvbV9wb2ludChhbHBoYSA9IDAuNikrCiAgZmFjZXRfZ3JpZCh+U2l0ZXMsIHNjYWxlcyA9ICJmcmVlX3giKSsKICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDkwLCB2anVzdCA9IDAuNSkpKwogIHNjYWxlX2NvbG9yX2JyZXdlcihwYWxldHRlID0gIlNldDEiKSsKICBnZ3RpdGxlKCJTcGVjaWVzIGNvbXBvc2l0aW9uIGJ5IHNpdGUgLSBBZ2FyaWNvbXljZXRlcyIpCiAgCmBgYAoKCmBgYHtyfQpBU1ZfYWdyaSA8LSBJVFNfdGF4YV84MF9nbG9tICU+JSAKICBmaWx0ZXIoY2xhc3MgPT0gIkFnYXJpY29teWNldGVzIikgJT4lIAogIHB1bGwoc2VxKQogIAoKcmFyX2FncmkgPC0gCkFTVl9zcCAlPiUgCiAgc2VsZWN0KGFsbF9vZihBU1ZfYWdyaSkpICU+JSAKICBhcy5tYXRyaXggJT4lIAogIGByb3duYW1lczwtYChBU1Zfc3AkU2FtcGxlKSAlPiUgCiAgYFtgKHJvd1N1bXMoLikgPiAwLCkgJT4lIAogIHJhcmVmeSh4ID0gLixzYW1wbGUgPSAyMDAwKSAKCgpgYGAKCgpgYGB7cn0KClNfZGZfYWdyaSA8LSAKcmFyX2FncmkgJT4lIAogIGRhdGEuZnJhbWUoUyA9IC4pICU+JSAKICBkcGx5cjo6YWRkX3Jvd25hbWVzKHZhciA9ICJJbmRleCIpICU+JSAKICBsZWZ0X2pvaW4oTWV0YSkgJT4lIAogIGZpbHRlcihUeXBlICVpbiUgYygiYWN0aXZlIiwgInBhc3NpdmUiKSkgJT4lIAogIGZpbHRlcihTYW1wbGVyICE9ICJEcm9uZSIpICU+JSAKICBtdXRhdGUoU2FtcGxlciA9IGZhY3RvcihTYW1wbGVyLCBsZXZlbHM9IHVuaXF1ZSguJFNhbXBsZXIpW2MoOCwxLDMsMiw1LDYsNCw3KV0pKSAKClNfZGZfYWdyaSAlPiUgCiAgZ2dwbG90KGFlcyh5ID0gUywgeCA9IGR1cmF0aW9uLCAgY29sb3VyID0gU2l0ZXMpKSsKICBmYWNldF9ncmlkKH5TYW1wbGVyLCBzY2FsZXMgPSAiZnJlZV94IikrCiAgZ2VvbV9saW5lKGFlcyhncm91cCA9IFNpdGVzKSwgc2l6ZSA9IDAuMiwgY29sb3VyID0gImdyZXkiKSsKICBnZW9tX3BvaW50KCkrCiAgdGhlbWVfbWluaW1hbCgpKwogIHNjYWxlX2NvbG9yX2JyZXdlcihwYWxldHRlID0gIlNldDEiKSsKICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDkwLCB2anVzdCA9IDAuNSksCiAgICAgICAgbGVnZW5kLnBvc2l0aW9uID0gImJvdHRvbSIpKwogIGdndGl0bGUoInJhcmVmaWVkIHJpY2huZXNzIC0gQWdhcmljb215Y2V0ZXMiKQpgYGAKYGBge3J9ClNfZGZfYWdyaSAlPiUgCiAgZmlsdGVyKFR5cGUgPT0gImFjdGl2ZSIpICU+JSAKICBncm91cF9ieShTaXRlcywgZHVyYXRpb24pICU+JSAKICBtdXRhdGUocmFua19TID0gcmFuayhTKSkgJT4lIAogIGdncGxvdChhZXMoeSA9IHJhbmtfUywgeCA9IFNpdGVzLCAgY29sb3VyID0gU2FtcGxlcikpKwogIGZhY2V0X3dyYXAofmR1cmF0aW9uLCBzY2FsZXMgPSAiZnJlZV95IiwgbnJvdyA9IDIpKwogIGdlb21fbGluZShhZXMoZ3JvdXAgPSBTYW1wbGVyKSwgc2l6ZSA9IDMsIGFscGhhID0gMC41KSsKIyAgZ2VvbV9wb2ludCgpKwogIHRoZW1lX21pbmltYWwoKSsKICBzY2FsZV9jb2xvcl9icmV3ZXIocGFsZXR0ZSA9ICJTZXQxIikrCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA5MCwgdmp1c3QgPSAwLjUpLAogICAgICAgIGxlZ2VuZC5wb3NpdGlvbiA9ICJib3R0b20iKSsKICBnZ3RpdGxlKCJyYXJlZmllZCByaWNobmVzcyAtIEFnYXJpY29teWNldGVzIikKICBzY2FsZV95X3JldmVyc2UoKQpgYGAKCgpgYGB7cn0KU19kZl9hZ3JpICU+JSAKICBsZWZ0X2pvaW4oZmxvd19yYXRlKSAlPiUgCiAgZmlsdGVyKFR5cGUgPT0gImFjdGl2ZSIgJiBTYW1wbGVyICE9ICJEcm9uZSIpICU+JSAKICBnZ3Bsb3QoYWVzKHggPSBhaXJfdm9sLCB5ID0gUywgY29sb3VyID0gU2FtcGxlcikpKwogIyBnZW9tX2xpbmUoYWVzKGdyb3VwID0gU2l0ZXMpLCBzaXplID0gMC4yLCBjb2xvdXIgPSAiZ3JleSIpKwogIGdlb21fcG9pbnQocG9zaXRpb24gPSBwb3NpdGlvbl9qaXR0ZXIod2lkdGggPSAwLjEpKSsKICBnZW9tX3Ntb290aChhZXMoZ3JvdXAgPSAxKSwgbWV0aG9kID0gImxtIiwgc2UgPSBUUlVFLCBjb2xvdXIgPSAiYmxhY2siLCBzaXplID0gMC4yKSsKICBmYWNldF9ncmlkKH5kdXJhdGlvbikrCiAgc2NhbGVfeF9sb2cxMCgpKwogIHNjYWxlX2NvbG9yX2JyZXdlcihwYWxldHRlID0gIlNldDEiKSsKICB0aGVtZV9taW5pbWFsKCkrCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gImJvdHRvbSIpKwogIGxhYnMoeCA9ICJzYW1wbGVkIGFpciB2b2x1bWUgKGwpIiwgdGl0bGUgPSAic2FtcGxlZCBhaXIgdm9sdW1lIikKICAKCmBgYAoKYGBge3J9CgpTX2RmX2FncmkgJT4lIAogIGxlZnRfam9pbihmbG93X3JhdGUpICU+JSAKICBsZWZ0X2pvaW4oRE5BQykgJT4lIAogIG11dGF0ZSh5aWVsZCA9IEROQUMgKiAyMDApICU+JSAKICBmaWx0ZXIoVHlwZSAlaW4lIGMoImFjdGl2ZSIsICJwYXNzaXZlIikgJiBTYW1wbGVyICE9ICJEcm9uZSIpICU+JSAKICBnZ3Bsb3QoYWVzKHggPSB5aWVsZCwgeSA9IFMsIGNvbG91ciA9IFNhbXBsZXIpKSsKICMgZ2VvbV9saW5lKGFlcyhncm91cCA9IFNpdGVzKSwgc2l6ZSA9IDAuMiwgY29sb3VyID0gImdyZXkiKSsKICBnZW9tX3BvaW50KHBvc2l0aW9uID0gcG9zaXRpb25faml0dGVyKHdpZHRoID0gMC4xKSkrCiAgZ2VvbV9zbW9vdGgoYWVzKGdyb3VwID0gMSksIG1ldGhvZCA9ICJsbSIsIHNlID0gVFJVRSwgY29sb3VyID0gImJsYWNrIiwgc2l6ZSA9IDAuMikrCiAgZmFjZXRfZ3JpZCh+ZHVyYXRpb24pKwogIHNjYWxlX3hfbG9nMTAoKSsKICBzY2FsZV9jb2xvcl9icmV3ZXIocGFsZXR0ZSA9ICJTZXQxIikrCiAgdGhlbWVfbWluaW1hbCgpKwogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJib3R0b20iKSsKICBsYWJzKHggPSAiRE5BIHlpZWxkIChuZykiLCB0aXRsZSA9ICJETkEgeWllbGQiKQogIApgYGAKCg==